package dinnerSimulation;

import java.io.Serializable;
import java.util.Collections;

import java.util.LinkedList;
import java.util.Random;
/**
 *  This class implement a Floor built of a Square matrix where the agent acts.
 * 
 * @see Square	 
 *
 */
public class Floor implements Serializable {

	private static final long	serialVersionUID	= -2524877175083650036L;

	public int length;

	public int width;

	public int initialDirt;

	private Square [][] floor;
	
	
	
	public enum roomType{
		KITCHEN, BEDROOM, LIVINGROOM, HALL, ENTRANCE
		
	};
	public roomType room[];
	/**
	 * 
	 * @param length		length of the floor
	 * @param width			width of the floor
	 * @param squareType	the square type (Clean, Dirty, Obstacle, Unknown)
	 */
	public Floor(int length, int width, Square.Type squareType){

		this.length = length;
		this.width = width;
		this.floor = new Square[length][width];
		this.room = new roomType[length];
		this.room[length-1] = roomType.ENTRANCE;
		for (int i = 0; i < length; i++)
			for (int j = 0; j < width; j++)
				this.floor[i][j] = new Square(squareType);
	}
	
	public Floor(int width){
		Square.Type squareType = Square.Type.CLEAN;
		this.length = 5;
		this.width = width;
		this.floor = new Square[length][width];
		this.room = new roomType[length];
		this.room[length-1] = roomType.ENTRANCE;
		for (int i = 0; i < length; i++)
			for (int j = 0; j < width; j++){
				if(i== length-1)
					squareType = Square.Type.GARDEN;
			
					this.floor[i][j] = new Square(squareType);
			}
			
	}
	public void setRoom(int pos, roomType type){
		room[pos]= type;
	}
	/**
	 * Generates randomly a floor scenario
	 * 
	 * @param numDirtySquares	quantity of dirty squares
	 * @param numObstacles		quantity of obstacles
	 */
	public Coord generateObject(int width){
		this.length = 5;
		

		//Order the rooms in random way
		
		LinkedList <roomType> rooms_r= new LinkedList<roomType>();
		
		rooms_r.add(roomType.BEDROOM);
		rooms_r.add(roomType.LIVINGROOM);
		rooms_r.add(roomType.HALL);
		rooms_r.add(roomType.KITCHEN);
		
		Collections.shuffle(rooms_r);
		
		//initialization of the rooms
		for(int i=0; i<this.room.length-1; i++){
			this.room[i] = rooms_r.get(i);
			System.out.println(this.room[i]);
		}
		
		this.room[length-1] = roomType.ENTRANCE;
		
		LinkedList <Square.Type> rooms_objects= new LinkedList<Square.Type>();
		
		for (int i = 0; i < length; i++){
		
				if(this.room[i]== roomType.BEDROOM){
					rooms_objects.add(Square.Type.SMOKING);
					rooms_objects.add(Square.Type.DOOR);
					for (int j = 2; j < width; j++){
						rooms_objects.add(Square.Type.CLEAN);
						
					}
					Collections.shuffle(rooms_objects);
					for(int k=0; k<width; k++)
						floor[i][k].type= rooms_objects.get(k);
					rooms_objects.clear();
				}
				if(this.room[i]== roomType.HALL){
					rooms_objects.add(Square.Type.FLOWERS);
					rooms_objects.add(Square.Type.DOOR);
					for (int j = 2; j < width; j++){
						rooms_objects.add(Square.Type.CLEAN);
						
					}
					Collections.shuffle(rooms_objects);
					for(int k=0; k<width; k++)
						floor[i][k].type= rooms_objects.get(k);
					rooms_objects.clear();
				}
				if(this.room[i]== roomType.LIVINGROOM){
					rooms_objects.add(Square.Type.TABLE);
					rooms_objects.add(Square.Type.DOOR);
					for (int j = 2; j < width; j++){
						rooms_objects.add(Square.Type.CLEAN);
						
					}
					Collections.shuffle(rooms_objects);
					for(int k=0; k<width; k++)
						floor[i][k].type= rooms_objects.get(k);
					rooms_objects.clear();
				}
				if(this.room[i]== roomType.KITCHEN){
					rooms_objects.add(Square.Type.MEAL);
					rooms_objects.add(Square.Type.DOOR);
					for (int j = 2; j < width; j++){
						rooms_objects.add(Square.Type.CLEAN);
						
					}
					Collections.shuffle(rooms_objects);
					for(int k=0; k<width; k++)
						floor[i][k].type= rooms_objects.get(k);
					rooms_objects.clear();
				}
				
			}

		
		
		
		
		//assign ciccio in a random position
		while(true){
			Random randomGen = new Random();
			int col = Math.abs(randomGen.nextInt()) % this.width;
			System.out.println("col" + col);
			
			int row = Math.abs(randomGen.nextInt()) % this.length;
			System.out.println("row" + row);
			
			if(this.floor[row][col].type== Square.Type.CLEAN){
				
				return new Coord(row, col);
			}
		}
				
				
		/*
		LinkedList<Cell> cells = new LinkedList<Cell>();

		for (int i = 0; i < length; i++)
			for (int j = 0; j < width; j++)
				if(floor[i][j].type == Square.Type.CLEAN)
					cells.add(new Cell(i, j));

		Collections.shuffle(cells);
		Random randomGen = new Random();
		int size = cells.size();
*/
		
	}
	/**
	 * 
	 * @return the current number of clean squares.
	 */
	public int squaresNowCleaned(){
		int cleanedSquare = 0;
		for (int i = 0; i < length; i++)
			for (int j = 0; j < width; j++)
				if(get(i,j) == Square.Type.CLEAN)
					cleanedSquare++;
		return cleanedSquare;
	}

	public void clear(){
		for (int i = 0; i < length; i++)
			for (int j = 0; j < width; j++){
				if(i==length-1){
					floor[i][j].type = Square.Type.GARDEN;
				}
				else
					floor[i][j].type = Square.Type.CLEAN;
				
			}
	}

	public void load(Floor floor){
		this.floor = floor.floor;
		this.width = floor.width;
		this.length = floor.length;
		this.room = floor.room;
	}


	/**
	 * Confirm if there is an obstacle in the position
	 * 
	 * @param i the row position of the square
	 * @param j the column position of the square
	 * 
	 * @return TRUE if there is an obstacle.
	 */
	public boolean obstacle(int i, int j) {
		return get(i,j) == Square.Type.DOOR;
	}

	/**
	 * 
	 * @param i the row position of the square
	 * @param j the column position of the square
	 * @return the type of the square
	 */
	public Square.Type get(int i, int j){
		if(i<0 || j<0 || i>=length || j>=width)
			return Square.Type.STATE;
		return this.floor[i][j].type;
	}

	/**
	 * Set the state of a square in the position (i,j).
	 * 
	 * @param i		the square's row
	 * @param j 	the square's column
	 * @param st	the square's state
	 */
	public void set(int i, int j, Square.Type st){
		if(i<0 || j<0 || i>=length || j>=width)
			return;
		this.floor[i][j].type = st;
	}

	/* Search object type and return position X Y* */
	public Coord search(Square.Type obj) {
		int i = 0;
		int j = 0;
		for (i = 0; i < this.length; i++)
			for (j = 0; j < this.width; j++) {
				if (this.floor[i][j].type.equals(obj)){
					
				//	System.out.println("L'oggetto : "+ obj.toString() +
				//			" si trova in room " +  i + " pos " + j );
					return new Coord(i, j);
				}
					
			}
		System.out.println("L'oggetto : "+ obj.toString() + " non � stato trovato." );

		return new Coord(-1, -1);
	}
	
	
}
